package dao.impl;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import model.impl.IntersectionImpl3;

import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.resotc.dao.IntersectionDAO;
import org.resotc.model.Intersection;

public class IntersectionDAOImpl extends AbstractXMLDAO implements IntersectionDAO {

	private final static String indexFileName = "intersection.xml";
	private HashMap<Integer, Intersection> intersections;
	
	public IntersectionDAOImpl() throws JDOMException, IOException {
		indexFile = new File(rootPath + "/" + indexFileName);
		loadXML();
		parseXML();
	}

	/**
	 * @see IntersectionDAO#getIntersection(int)
	 */
	public Intersection getIntersection(int id) {
		return intersections.get(id);
	}
	
	/**
	 * @see IntersectionDAO#setIntersection()
	 */
	public void setIntersection(Intersection intersection)
	{
		this.intersections.put(intersection.getId(), intersection);
	}
	/**
	 * @see IntersectionDAO#getIntersections()
	 */
	public HashMap<Integer, Intersection> getIntersections() {
		return intersections;
	}

	/**
	 * @see IntersectionDAO#createIntersection(Intersection)
	 */
	public void createIntersection(Intersection intersection) {
		createAndUpdateIntersection(intersection);
	}

	/**
	 * @see IntersectionDAO#updateIntersection(Intersection)
	 */
	public void updateIntersection(Intersection intersection) {
		createAndUpdateIntersection(intersection);
	}

	/**
	 * @see IntersectionDAO#deleteIntersection(int)
	 */
	public void deleteIntersection(int id) {
		Element rootElement = indexXMLInstance.getRootElement();
		Iterator<Element> it = rootElement.getChild("intersections").getChildren().iterator();

		while (it.hasNext()) {
			Element centroid = it.next();
			int centroidId = Integer.parseInt(centroid.getChildText("id"));

			if (centroidId == id) {
				it.remove();
				break;
			}
		}
		intersections.remove(intersections.get(id));
		storeXML();
	}

	/**
	 * @see IntersectionDAO#intersectionExists(int)
	 */
	public boolean intersectionExists(int id) {
		return intersections.containsKey(id);
	}

	/**
	 * Creates an new intersection or updates an existing one.
	 * 
	 * @param intersection
	 */
	private void createAndUpdateIntersection(Intersection intersection) {
		Element newElement = new Element("intersection");

		newElement.addContent(new Element("id").setText(String.valueOf(intersection.getId())));
		newElement.addContent(new Element("phasesystem").setText(String.valueOf(intersection.getPhaseSystem())));
		newElement.addContent(new Element("left").setText(String.valueOf(intersection.isQueueLeft())));
		newElement.addContent(new Element("x").setText(String.valueOf(intersection.getX())));
		newElement.addContent(new Element("y").setText(String.valueOf(intersection.getY())));

		if (intersections.containsKey(intersection.getId())) {
			Element rootElement = indexXMLInstance.getRootElement();
			Element intersectionElements = rootElement.getChild("intersections");

			List<Element> intersectionList = new ArrayList<Element>(intersectionElements.getChildren());

			for (Element exstIntersection : intersectionList) {
				int id = Integer.parseInt(exstIntersection.getChildText("id"));
				if (id == intersection.getId()) {
					intersectionElements.removeContent(exstIntersection);
					rootElement.getChild("intersections").addContent(newElement);
					intersections.put(intersection.getId(), intersection);
					break;
				}
			}
		}
		storeXML();
	}

	/**
	 * Parses the intersection.xml file.
	 * 
	 * @throws IOException
	 * @throws JDOMException
	 */
	private void parseXML() throws JDOMException, IOException {
		Element rootElement = indexXMLInstance.getRootElement();
		Element element = rootElement.getChild("intersections");

		intersections = new HashMap<Integer, Intersection>();
		List<Element> list = element.getChildren();

		for (Element component : list) {

			int id = Integer.parseInt(component.getChildText("id"));
			boolean isQueueLeft = Boolean.parseBoolean(component.getChildText("left"));
			double xPos = Double.parseDouble(component.getChildText("x"));
			double yPos = Double.parseDouble(component.getChildText("y"));

			Intersection intersection = new IntersectionImpl3(id, isQueueLeft, xPos, yPos);
			intersections.put(id, intersection);
		}
	}
}
